﻿using System;
using System.Linq;
using BusinessBingo.CommandHandlers.Base;
using BusinessBingo.CommandHandlers.Interfaces;
using BusinessBingo.CommandHandlers.Results;
using BusinessBingo.Commands;
using BusinessBingo.Data.Filter;
using BusinessBingo.Data.Interfaces;
using BusinessBingo.Model;
using BusinessBingo.Model.Interfaces;

namespace BusinessBingo.CommandHandlers
{
    public class CreateNewGameCommandHandler :
        BaseCommandHandler, ICreateNewGameCommandHandler
    {
        private IGameRepository _gameRepository;

        public CreateNewGameCommandHandler(
            IGameRepository gameRepository,
            IValidationState validationState,
            IUnitOfWork unitOfWork) :
            base(validationState, unitOfWork)
        {
            this._gameRepository = gameRepository;
        }

        public CreateNewGameCommandHandlerResult Execute(CreateNewGameCommand createNewGameCommand)
        {
            CreateNewGameCommandHandlerResult result = new CreateNewGameCommandHandlerResult();

            if(createNewGameCommand == default(CreateNewGameCommand))
                throw new ArgumentNullException("CreateNewGameCommand");
            if(createNewGameCommand.GroupId == default(Guid))
                this._validationState.AddError<CreateNewGameCommand>(x => x.GroupId, ErrorTypes.Empty);

            if (this._validationState.IsValid == false)
                return result;

            GameFilter filter = new GameFilter();
            filter.WithGroupId = createNewGameCommand.GroupId;
            filter.OnlyLastGame = true;

            Game game = new Game();
            game.GroupId = createNewGameCommand.GroupId;

            Game lastGame = this._gameRepository.GetItems(null, null, filter).SingleOrDefault();

            int number = 1;
            if (lastGame != null) number = lastGame.Number + 1;

            game.Number = number;

            game = this._gameRepository.AddItem(game);

            base.Complete();

            result.Game = game;
            result.Succeeded = true;

            return result;
        }
    }
}